import axios, { type AxiosRequestConfig, Method } from 'axios'
import { type AllApiPath } from '@/config/apis'
import useLanguageStore from '@/stores/language'
import useUserStore from '@/stores/user'
import { ElMessage, ElLoading } from 'element-plus'

interface Headers {
  'Accept-Language': string
  Authorization?: string
}
const instance = axios.create({
  timeout: 60000,
})

// 添加请求拦截器
instance.interceptors.request.use(
  (config) => {
    // 在发送请求之前做些什么
    const languageStore = useLanguageStore()
    const userStore = useUserStore()
    const token = userStore.token || null

    const headers: Headers = {
      'Accept-Language': languageStore['Accept-Language'],
    }

    if (token) headers.Authorization = `Bearer ${token}`

    return { ...config, headers: { ...config.headers, ...headers } }
  },
  (error) => {
    // 对请求错误做些什么
    return Promise.reject(error)
  }
)

// 添加响应拦截器
instance.interceptors.response.use(
  (response) => {
    /**
     * 2xx 范围内的状态码都会触发该函数
     * 对响应数据做点什么
     * 添加APOLLO返回格式
     */
    if (
      Object.hasOwnProperty.call(response.data, 'isSuccess') &&
      !response.data.isSuccess
    ) {
      ElMessage({
        message: response.data.message,
        showClose: true,
        duration: 3,
        type: 'error',
      })
      return Promise.reject(response)
    }
    return response.data.data || response.data
  },
  (error) => {
    /**
     * 超出 2xx 范围的状态码都会触发该函数
     * 对响应错误做点什么
     */
    ElMessage({
      message: error.message,
      showClose: true,
      duration: 3,
      type: 'error',
    })
    return Promise.reject(error)
  }
)

interface AxiosOption extends AxiosRequestConfig {
  url: AllApiPath
  method: Method
}

interface ClientResponse<T = any> {
  isSuccess: boolean
  message: string | null
  data: T
}

export default {
  basics<T>(option: AxiosOption) {
    return instance<ClientResponse<T>>(option).then((response) => {
      return response.data
    })
  },
  fetch<T>(option: AxiosOption) {
    const loading = ElLoading.service({
      lock: true,
      text: 'Loading',
      background: 'rgba(0, 0, 0, 0.7)',
    })
    return this.basics<T>(option).finally(() => loading.close())
  },
  get<T>(url: AllApiPath, params?: any) {
    const loading = ElLoading.service({
      lock: true,
      text: 'Loading',
      background: 'rgba(0, 0, 0, 0.7)',
    })
    return instance.get<T>(url, { params }).finally(() => loading.close())
  },
}
